program constraint_dist;
    class Test;
        // SystemVerilog 只能随机化 2 值数据，但数据类型可以是2值或4值
        rand int src, dst;
        constraint cdist {
            // :=操作符表示值范围内的每一个值的权重是相同的
            src dist {0 := 40, [1:3] := 60};
            // src = 0, weight = 40/220
            // src = 1, weight = 60/220
            // src = 2, weight = 60/220
            // src = 3, weight = 60/220

            // :/操作符表示权重需要平均分到值范围内的每一个值
            dst dist {0 :/ 40, [1:3] :/ 60};
            // dst = 0, weight = 40/100
            // dst = 1, weight = 20/100
            // dst = 2, weight = 20/100
            // dst = 3, weight = 20/100
        }
    endclass

    initial begin
        int N = 1000000;
        Test t = new();
        int src_count[4] = '{0, 0, 0, 0};
        int dst_count[4] = '{0, 0, 0, 0};
        int src_sum = 0;
        int dst_sum = 0;

        // 统计src和dst的分布
        for (int i = 0; i < N; i++) begin
            if (t.randomize()) begin
                src_count[t.src]++;
                dst_count[t.dst]++;
            end
        end

        // 打印分布结果
        $display("src distribution:");
        src_sum = src_count[0] + src_count[1] + src_count[2] + src_count[3];
        for (int i = 0; i < 4; i++) begin
            $display("src=%0d, count=%0d, prob=%f", i, src_count[i], 1.0 * src_count[i] / src_sum);
        end
        $display("dst distribution:");
        dst_sum = dst_count[0] + dst_count[1] + dst_count[2] + dst_count[3];
        for (int i = 0; i < 4; i++) begin
            $display("dst=%0d, count=%0d, prob=%f", i, dst_count[i], 1.0 * dst_count[i] / dst_sum);
        end
    end
endprogram


/* Output in Vivado:
src distribution:
src=0, count=182473, prob=0.182473
src=1, count=272262, prob=0.272262
src=2, count=272804, prob=0.272804
src=3, count=272461, prob=0.272461
dst distribution:
dst=0, count=400019, prob=0.400019
dst=1, count=199843, prob=0.199843
dst=2, count=199704, prob=0.199704
dst=3, count=200434, prob=0.200434
*/

/* Output in VCS:
src distribution:
src=0, count=181431, prob=0.181431
src=1, count=273493, prob=0.273493
src=2, count=272889, prob=0.272889
src=3, count=272187, prob=0.272187
dst distribution:
dst=0, count=400246, prob=0.400246
dst=1, count=200097, prob=0.200097
dst=2, count=200181, prob=0.200181
dst=3, count=199476, prob=0.199476
*/

/* Output in QuestaSim:
src distribution:
src=0, count=181626, prob=0.181626
src=1, count=273188, prob=0.273188
src=2, count=272314, prob=0.272314
src=3, count=272872, prob=0.272872
dst distribution:
dst=0, count=400164, prob=0.400164
dst=1, count=199808, prob=0.199808
dst=2, count=200500, prob=0.200500
dst=3, count=199528, prob=0.199528
*/